<template>
    <div ref="wrapper" class="drag-bar-wrapper">
        <div ref="header" class="drag-bar-header">
            <!-- 头部区域 -->
            <slot name="header" />
        </div>
        <div class="drag-bar-content">
            <!-- 主内容区域 -->
            <slot name="default" />
        </div>
        <div class="drag-bar-footer">
            <!-- 底部区域 -->
            <slot name="footer" />
        </div>
    </div>
</template>
<script>
export default {
    data() {
        return {
            wrapperDom: null,
            headerDom: null,

            disX: 0,
            disY: 0,

            minLeft: 0,
            maxLeft: 0,

            minTop: 0,
            maxTop: 0,

            prevLeft: 0,
            prevTop: 0,
        };
    },
    methods: {
        initDrag() {
            this.wrapperDom = this.$refs.wrapper;
            this.headerDom = this.$refs.header;
            this.headerDom.addEventListener('mousedown', this.onMousedown, false);//点击头部区域拖拽
        },
        onMousedown(e) {
            this.disX = e.clientX - this.headerDom.offsetLeft;
            this.disY = e.clientY - this.headerDom.offsetTop;
            this.minLeft = this.wrapperDom.offsetLeft;
            this.minTop = this.wrapperDom.offsetTop;

            this.maxLeft =
                window.innerWidth - this.minLeft - this.wrapperDom.offsetWidth;
            this.maxTop =
                window.innerHeight - this.minTop - this.wrapperDom.offsetHeight;

            const { left, top } = getComputedStyle(this.wrapperDom, false);
            this.prevLeft = parseFloat(left);
            this.prevTop = parseFloat(top);
            document.addEventListener('mousemove', this.onMousemove, false);
            document.addEventListener('mouseup', this.onMouseup, false);
            document.body.style.userSelect = 'none'; //消除拖拽中选中文本干扰
        },
        onMousemove(e) {
            let left = e.clientX - this.disX;
            let top = e.clientY - this.disY;

            if (-left > this.minLeft) {
                left = -this.minLeft;
            } else if (left > this.maxLeft) {
                left = this.maxLeft;
            }

            if (-top > this.minTop) {
                top = -this.minTop;
            } else if (top > this.maxTop) {
                top = this.maxTop;
            }

            this.wrapperDom.style.left = this.prevLeft + left + 'px';
            this.wrapperDom.style.top = this.prevTop + top + 'px';
        },
        onMouseup() {
            document.removeEventListener('mousemove', this.onMousemove, false);
            document.removeEventListener('mouseup', this.onMouseup, false);
            document.body.style.userSelect = 'auto'; //恢复文本可选中
        },
    },
    mounted() {
        this.initDrag();
    }
};
</script>
 
<style scoped>
.drag-bar-wrapper {
    position: fixed;
    z-index: 10;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    flex-direction: column;
}

.drag-bar-header {
    background-color: #eee;
    cursor: move;
    /*拖拽鼠标样式*/
}

.drag-bar-content {
    background-color: #fff;
}

.drag-bar-footer {
    background-color: #fff;
}
</style>